﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xunit;
using M3G;

namespace MyTestProject {

    public class TestStencil {
        [Fact]
        public void TestConstructor () {
            var stc = new Stencil ();

            Assert.Equal (0xffffffffu, stc.StencilWriteMask[Stencil.Front]);
            Assert.Equal (0xffffffffu, stc.StencilWriteMask[Stencil.Back]);

            // parameters are
            //  [0] func
            //  [1] ref
            //  [2] mask
            //  [3] stencilFailOp,
            //  [4] stencilPassDepthFailOp,
            //  [5] stencilPassDepthPassOP

            var parms = stc.StencilParameters[Stencil.Front];
            Assert.Equal (CompositingMode.Always, parms[0]);
            Assert.Equal (0           , parms[1]);
            Assert.Equal (0xffffffffu , (uint)parms[2]);
            Assert.Equal (Stencil.Keep, parms[3]);
            Assert.Equal (Stencil.Keep, parms[4]);
            Assert.Equal (Stencil.Keep, parms[5]);

            parms = stc.StencilParameters[Stencil.Back];
            Assert.Equal (CompositingMode.Always, parms[0]);
            Assert.Equal (0           , parms[1]);
            Assert.Equal (0xffffffffu , (uint)parms[2]);
            Assert.Equal (Stencil.Keep, parms[3]);
            Assert.Equal (Stencil.Keep, parms[4]);
            Assert.Equal (Stencil.Keep, parms[5]);
        }

        [Fact]
        public void TestSetStencilWriteMask () {
            var stc = new Stencil ();

            stc.SetStencilWriteMask(Stencil.Front, 0x12345678);
            stc.SetStencilWriteMask(Stencil.Back, 0x87654321);

            Assert.Equal (0x12345678u, stc.StencilWriteMask[Stencil.Front]);
            Assert.Equal (0x87654321u, stc.StencilWriteMask[Stencil.Back]);
        }

        [Fact]
        public void TestSetStencilFunc () {
            var stn = new Stencil ();

            stn.SetStencilFunc (Stencil.Front, CompositingMode.Never, 1, 0x12345678);
            stn.SetStencilFunc (Stencil.Back , CompositingMode.LEqual, 2, 0x87654321);

            var parms = stn.StencilParameters[Stencil.Front];
            Assert.Equal (CompositingMode.Never, parms[0]);
            Assert.Equal (1           , parms[1]);
            Assert.Equal (0x12345678u, (uint)parms[2]);

            parms = stn.StencilParameters[Stencil.Back];
            Assert.Equal (CompositingMode.LEqual, parms[0]);
            Assert.Equal (2           , parms[1]);
            Assert.Equal (0x87654321u, (uint)parms[2]);
        }

        [Fact]
        public void TestSetStencilOps () {
            var stc = new Stencil ();

            stc.SetStencilOps (Stencil.Front, Stencil.Zero, Stencil.Incr, Stencil.DecrWrap);
            stc.SetStencilOps (Stencil.Back, Stencil.Replace, Stencil.Decr, Stencil.Invert);

            var parms = stc.StencilParameters[Stencil.Front];
            Assert.Equal (Stencil.Zero    , parms[3]);
            Assert.Equal (Stencil.Incr    , parms[4]);
            Assert.Equal (Stencil.DecrWrap, parms[5]);

            parms = stc.StencilParameters[Stencil.Back];
            Assert.Equal (Stencil.Replace, parms[3]);
            Assert.Equal (Stencil.Decr   , parms[4]);
            Assert.Equal (Stencil.Invert , parms[5]);
        }

        [Fact]
        public void TestDuplicate () {
            var stn = new Stencil ();
            stn.SetStencilWriteMask (Stencil.Front, 0x12345678);
            stn.SetStencilWriteMask (Stencil.Back, 0x87654321);
            stn.SetStencilFunc (Stencil.Front, CompositingMode.Never, 1, 0x12345678);
            stn.SetStencilFunc (Stencil.Back, CompositingMode.LEqual, 2, 0x87654321);
            stn.SetStencilOps (Stencil.Front, Stencil.Zero, Stencil.Incr, Stencil.DecrWrap);
            stn.SetStencilOps (Stencil.Back, Stencil.Replace, Stencil.Decr, Stencil.Invert);
            stn.UserID = 100;

            var dup = (Stencil)stn.Duplicate ();


            // parameters are
            //  [0] func
            //  [1] ref
            //  [2] mask
            //  [3] stencilFailOp,
            //  [4] stencilPassDepthFailOp,
            //  [5] stencilPassDepthPassOP

            var srcFrontParams = stn.StencilParameters[Stencil.Front];
            var dupFrontParams = dup.StencilParameters[Stencil.Front];
            var srcBackParams  = stn.StencilParameters[Stencil.Back];
            var dupBackParams  = dup.StencilParameters[Stencil.Back];

            Assert.Equal (stn.StencilWriteMask[Stencil.Front], dup.StencilWriteMask[Stencil.Front]);
            Assert.Equal (stn.StencilWriteMask[Stencil.Back], dup.StencilWriteMask[Stencil.Back]);
            
            Assert.Equal (srcFrontParams[0], srcFrontParams[0]);
            Assert.Equal (srcFrontParams[1], srcFrontParams[1]);
            Assert.Equal (srcFrontParams[2], srcFrontParams[2]);
            Assert.Equal (srcFrontParams[3], srcFrontParams[3]);
            Assert.Equal (srcFrontParams[4], srcFrontParams[4]);
            Assert.Equal (srcFrontParams[5], srcFrontParams[5]);

            Assert.Equal (srcBackParams[0], srcBackParams[0]);
            Assert.Equal (srcBackParams[1], srcBackParams[1]);
            Assert.Equal (srcBackParams[2], srcBackParams[2]);
            Assert.Equal (srcBackParams[3], srcBackParams[3]);
            Assert.Equal (srcBackParams[4], srcBackParams[4]);
            Assert.Equal (srcBackParams[5], srcBackParams[5]);

            Assert.Equal (stn.UserID, dup.UserID);
        }

    }
}
